package com.lyf.scm.plan.domain.remote.item.facade;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.common.enums.ResponseMsg;
import com.lyf.scm.plan.api.dto.CategoryBaseInfoDTO;
import com.lyf.scm.plan.domain.remote.item.ItemCoreRemote;
import com.lyf.scm.plan.domain.remote.item.dto.*;
import com.rome.arch.core.clientobject.Response;
import com.rome.arch.core.exception.RomeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * description:
 * 外部service调用Facade
 *
 * @author: haodong
 * @data: 2020/7/18 14:06
 */
@Service
@Slf4j
public class ItemCoreFacade {

    @Resource
    private ItemCoreRemote itemCoreRemote;


    /**
     * 单位换算
     *
     * @param skuCodeList
     * @param unitType
     * @return
     */
    public List<SkuUnitDTO> getConversionRatio(List<String> skuCodeList, Long unitType) {
        log.info("根据sku和单位type获取sku单位换算比例:skuCodeList:{},unitType:{}", skuCodeList, unitType);
        if (CollectionUtils.isEmpty(skuCodeList)) {
            return null;
        }
        Response<List<SkuUnitDTO>> response = itemCoreRemote.getSkuUnit(skuCodeList, unitType);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }

        return response.getData().stream().filter(distinctByKey(SkuUnitDTO::getSkuCode)).collect(Collectors.toList());
    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


    public PageInfo<SkuInfosDTO> getAllCategoryIdBySkuCode(Integer pageNum, Integer pageSize, List<String> skuCodes) {
        log.info("根据商品code集合获取对应品类id集合:pageNum,pageSize,skuCodes:{}", pageNum + ",", pageSize + ",", skuCodes);
        Response<PageInfo<SkuInfosDTO>> response = itemCoreRemote.getAllCategoryIdBySkuCode(pageNum, pageSize, skuCodes);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2002.getCode(), ResponseMsg.EXCEPTION_2002.getMsg());
        }
        return response.getData();
    }

    /**
     * 根据品类叶子节点id获取大中小品类信息
     *
     * @param ids
     * @return
     */
    public List<CategorySimpleDTO> getAllCategoryByCategoryId(List<Integer> ids) {
        Response<List<CategorySimpleDTO>> response = itemCoreRemote.getAllCategoryByCategoryId(ids);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2002.getCode(), ResponseMsg.EXCEPTION_2002.getMsg());
        }
        return response.getData();
    }


    public List<CategoryDTO> categoryListByCategoryCodes(List<Long> categoryCodes) {
        log.info("批量通过categoryCodes查询后台类目信息入参:categoryCodes:{}", categoryCodes);
        Response<List<CategoryDTO>> response = itemCoreRemote.categoryListByCategoryCodes(categoryCodes);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData();
    }

    /**
     * 根据品类的code查询后台类目信息(包括下一级类目的信息)
     *
     * @param stringList
     * @return
     */
    public List<CategoryBaseInfoDTO> listByCategoryCodes(List<String> stringList) {
        log.info("根据品类的code查询后台类目信息(包括下一级类目的信息)：stringList：{}", stringList);
        Response<List<CategoryBaseInfoDTO>> response = itemCoreRemote.listByCategoryCodes(stringList);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2002.getCode(), ResponseMsg.EXCEPTION_2002.getMsg());
        }
        return response.getData();
    }

    /**
     * 批量根据sku编码获取skuInfo
     *
     * @param skuList
     * @return
     */
    public List<SkuInfoDTO> listBySkuList(List<String> skuList) {
        log.info("批量根据sku编码获取skuInfo：skuList：{}", skuList);
        Response<List<SkuInfoDTO>> response = itemCoreRemote.listSkuInfoByCodes(skuList);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2002.getCode(), ResponseMsg.EXCEPTION_2002.getMsg());
        }
        return response.getData();
    }

    public List<SkuUnitDTO> getUtilInfoBySkuCode(List<UnitCodeExtParamDTO> list) {
        log.info("批量通过skuCode和单位名称查询基础单位换算关系，参数：{}", list);
        Response<PageInfo<SkuUnitDTO>> response = itemCoreRemote.getUtilInfoBySkuCode(list, list.size());
        log.info("批量通过skuCode和单位名称查询基础单位换算关系，响应：{}", response);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData().getList();
    }

    public List<SkuSalePriceResultDTO> selectSalePrice(List<SearchPriceParamDTOS> searchPriceParamDTOS) {
        log.info("批量根据skuCode，channelCode，UnitCode批量查询当前时间价格入参:searchPriceParamDTOS:{}", JSON.toJSONString(searchPriceParamDTOS));
        Response<List<SkuSalePriceResultDTO>> response = itemCoreRemote.selectSalePrice(searchPriceParamDTOS);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2002.getCode(), ResponseMsg.EXCEPTION_2002.getMsg());
        }
        return response.getData();
    }

    public List<SkuUnitExtDTO> getSkuUnitByCodeAndType(List<String> skuCodes, Integer skuUintType) {
        log.info("批量通过skuCodes与skuUintType查询sku单位信息，参数：{}", JSON.toJSONString(skuCodes), skuUintType);
        Response<List<SkuUnitExtDTO>> response = itemCoreRemote.getSkuUnitByCodeAndType(skuCodes, skuUintType);
        log.info("批量通过skuCodes与skuUintType查询sku单位信息，响应：{}", JSON.toJSONString(response));
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData();
    }

    /**
     * 查询全量的sku信息，只返回skuid,code(默认只查单品)
     *
     * @param type
     * @return {@link List<SkuIdCodeDTO>}
     **/
    public List<SkuIdCodeDTO> selectAllSkuField(String type) {
        Response<List<SkuIdCodeDTO>> response = itemCoreRemote.selectAllSkuField(type);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData();
    }

    /**
     * 根据sku查到商品详情
     *
     * @param skuCodeList
     * @return {@link List<SkuIdCodeDTO>}
     **/
    public List<SkuInfoDTO> skuListBySkuCodes(List<String> skuCodeList) {
        Response<List<SkuInfoDTO>> response = itemCoreRemote.skuListBySkuCodes(skuCodeList);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData();
    }

    public List<TagSkuInfoDTO> getSkuTagGroupBySkuCodes(List<String> skuCodes,Integer type){
        log.info("根据skuCode批量查询商品PM入参:skuCodes:{},type:{}", skuCodes,type);
        Response<List<TagSkuInfoDTO>> response = itemCoreRemote.getSkuTagGroupBySkuCodes(skuCodes, type);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData();
    }

    /**
     * 根据sku+渠道+单位 查询价格
     * @param list
     * @return
     */
    public List<SkuPriceDTO> getSkuPrice(List<SkuPriceDTO> list) {
        log.info("查询sku价格入参：{}", list);
        Response<PageInfo<SkuPriceDTO>> response = itemCoreRemote.getPriceBySkuCodeList(list);
        if (!ResponseMsg.SUCCESS.getCode().equals(response.getCode())) {
            throw new RomeException(response.getCode(), response.getMsg());
        }
        return response.getData() != null ? response.getData().getList() : null;
    }
}
